package javango.forms.fields;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import com.google.inject.Inject;

import javango.forms.ValidationException;
import javango.forms.fields.annotations.CharFieldProperties;
import javango.forms.widgets.TextInputWidget;
import javango.forms.widgets.Widget;
import javango.forms.widgets.WidgetFactory;

public class CharField extends AbstractField<String> {

	@Inject
	public CharField(WidgetFactory widgetFactory) {
		super(widgetFactory);
	}

	private Integer maxLength;
	
	public void handleAnnotation(Annotation annotation) {
		super.handleAnnotation(annotation);
		if (!(annotation instanceof CharFieldProperties)) return;
		
		CharFieldProperties props = (CharFieldProperties)annotation;
		if (props.maxLength() != 0) {
			this.setMaxLength(props.maxLength());
		}
	}
	
	@Override
	public String clean(String value, Map<String, String> errors) throws ValidationException {
		if (StringUtils.isEmpty(value)) {
			if (isRequired()) { 
				errors.put(getName(), REQUIRED_ERROR);
			} else if (isAllowNull()) {
				return null;
			}
		}
		
		if (getMaxLength() != null && getMaxLength() > 0) {
			if (value.length() > getMaxLength()) {
				errors.put(getName(), 
						String.format("Ensure this value has at most %d characters (it has %d).",
								getMaxLength(),
								value.length()));
			}
		}
		return value;
	}

	public Integer getMaxLength() {
		return maxLength;
	}

	public void setMaxLength(Integer maxLength) {
		this.maxLength = maxLength;
	}

	@Override
	public Map<String, String> getWidgetAttrs() {
		Map<String, String> widgetAttrs = super.getWidgetAttrs();
		
		if (widgetAttrs != null) {
			if (maxLength != null && !widgetAttrs.containsKey("maxlength")) {
				widgetAttrs.put("maxlength", maxLength.toString());
			}
			return widgetAttrs;
		}
		
		if (maxLength != null) {
			widgetAttrs = new HashMap<String, String>();
			widgetAttrs.put("maxlength", maxLength.toString());
			return widgetAttrs;
		}
		return null;
	}
		
}
